
package pos.control;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import pos.entity.Order;
import pos.exception.POSException;
import pos.interfaces.Messages;
import pos.storage.db.sql.SQL;
import pos.util.Validate;
import pos.Pos;
import pos.entity.PaymentDetails;
import pos.entity.PurchasedItem;
import pos.storage.db.mysql.SelectQueryTableModel;
import pos.util.paymentValidate;
import pos.util.IDGenerator;
/**
 * A control object class that takes customer's payment information from the
 * boundary objects and also validates all the payment information and process
 * the payment.
 * @author wei zhang
 */
public class PaymentControl implements Messages {
    
    private Connection conn = null;
    
    /**
     * Get the connection
     * @return
     */
    public Connection getConn() {
        return conn;
    }

    /**
     * set the connection
     * @param conn
     */
    public void setConn(Connection conn) {
        this.conn = conn;
    }

    /**
     * Check if all the payment information is valid and process the customer's
     * payment.
     * @param paymentDetails
     * @param order
     * @param conn
     * @return
     * @throws POSException
     * @throws SQLException
     */
    public int handlePaymentDetails(PaymentDetails paymentDetails, Order order, Connection conn)
            throws POSException,SQLException { 
          setConn(conn);
          return handlePaymentDetails(paymentDetails, order);
      }
    
    /**
     * Check if all the payment information is valid and process the customer's
     * payment.
     * @param card_num
     * @param phone_num
     * @param payment_cardNum
     * @param security_num
     * @param name
     * @param expire_month
     * @param expire_year
     * @param card_type
     * @return
     * @throws POSException
     * @throws SQLException
     */
    public int handlePaymentDetails(PaymentDetails paymentDetails, Order order)
            throws POSException,SQLException {
        
        if(conn == null){
            conn = Pos.custConn;
        }

        IDGenerator newCardNum = new IDGenerator();
        long paymentDetails_id;
        String card_num = paymentDetails.getCardNumber();
        String phone_num = paymentDetails.getPhoneNumber();
        String payment_cardNum = paymentDetails.getPaymentCardNumber();
        String security_num = paymentDetails.getSecurityNumber();
        String name = paymentDetails.getName();
        String expire_month = paymentDetails.getExpiryMonth();
        String expire_year = paymentDetails.getExpiryYear();
        String card_type = paymentDetails.getCardType();
        long customerId = 0;
        long orderId = order.getOrderId();

        paymentDetails.setPaymentDetailsId(newCardNum.getID());
        paymentDetails_id = paymentDetails.getPaymentDetailsId();

        paymentValidate validate = new paymentValidate();
        Validate validate1 = new Validate();

        ResultSet rs1;
        ResultSet rs2;

        String firstName = null;
        String lastName  = null;
        int paymentSuccess = 3;
        boolean isMember = false;
        boolean provideMemberInfo = false;     
        try {
            PreparedStatement stmt1 = conn.prepareStatement(SQL.SelectCustomerWithPhoneNum);
            PreparedStatement stmt2 = conn.prepareStatement(SQL.SelectCustomerWithStoreCardNUm);
            PreparedStatement stmt3 = conn.prepareStatement(SQL.INSERT_PAYMENTDETAILS);
            card_type = validate.validTextInput(card_type);          
            if(!card_type.equalsIgnoreCase("cash")){
                if(card_type.equalsIgnoreCase("credit")){
                    security_num = validate.validCardSecurityNumber(security_num);
                }
                payment_cardNum = validate.validPaymentCardNumber(payment_cardNum);

                expire_month = validate.validMonth(expire_month);
                expire_year = validate.validYear(expire_year);
            }          
            if (card_num.equals("")) {
                if (!phone_num.equals("")) {
                    provideMemberInfo = true;
                    phone_num = validate1.validPhoneNumber(phone_num);
                    stmt1.setLong(1, Long.parseLong(phone_num));
                    rs1 = stmt1.executeQuery();
                    while (rs1.next()) {
                        firstName = rs1.getString(1);
                        lastName = rs1.getString(2);
                        if (firstName != null && lastName != null) {
                            customerId = Long.parseLong(rs1.getString(3));
                            isMember = true;
                        }
                    }
                }
            } else {
                provideMemberInfo = true;
                card_num = validate1.validStoreCardNumber(card_num);
                stmt2.setString(1, card_num);
                rs2 = stmt2.executeQuery();
                while (rs2.next()) {
                    firstName = rs2.getString(1);
                    lastName = rs2.getString(2);
                    if (firstName != null && lastName != null) {
                        customerId = Long.parseLong(rs2.getString(3));
                        isMember = true;
                    }
                }

            }

            //Use for valid the payment in the future
            if(paymentSuccess == 3){
                int returnStatus = 1;
                if(isMember == true){
                    //We should have a varibale for CustomerId, and OrderId
                    returnStatus = 1;
                } else if(provideMemberInfo == true){
                    returnStatus = 2;
                   //return 2;
                } else {
                    returnStatus = 3;
                   
                }

                processOrder(order, conn);
                stmt3.setLong(1,paymentDetails_id); 
                stmt3.setLong(2,customerId);
                stmt3.setLong(3,orderId);
                stmt3.setString(4,card_type);
                stmt3.setString(5,payment_cardNum);
                stmt3.execute();
                return returnStatus;
            }
        } catch (SQLException ex) {           
            ex.printStackTrace();
        } catch (POSException e){          
            throw new POSException(e.getMessage(), e);
        }

        return -1;
    }

    /**
     * Processes the order
     * @param order
     * @return
     * @throws SQLException 
     */
    public int processOrder(Order order, Connection con)throws SQLException{
        try{
            
        PreparedStatement orderInsertStmt = null;
        String sql = SQL.INSERTORDER;
        orderInsertStmt = con.prepareStatement(sql);
        
        orderInsertStmt.setLong(1, order.getOrderId());
            orderInsertStmt.setDate(2, order.getDateTimeCreated());
            //orderInsertStmt.setLong(3, order.getStoreId());
            orderInsertStmt.setLong(3, 1);//Hardcoding as of now
            orderInsertStmt.setString(4, order.getOrderTransactionSource());

            orderInsertStmt.setDouble(5, order.getOrderTotalBasePrice());
            orderInsertStmt.setDouble(6, order.getOrderTotalAdjustedAmount());
            orderInsertStmt.setDouble(7, order.getOrderTotalPrice());
            //orderInsertStmt.setLong(8, order.getOrderTakenByEmployeeId());
            orderInsertStmt.setLong(8, 1);//Hardcoding as of now
            
            orderInsertStmt.setDate(9, order.getDateTimeCreated());
            orderInsertStmt.setDate(10, order.getOrderDateModified());
            orderInsertStmt.setLong(11, order.getCustomerId());
           orderInsertStmt.executeUpdate();
           if(insertPurchasedItems(order, conn) == -1){
               return -1;
           }
            return 1;
        }
        catch(SQLException e){
            //e.printStackTrace();
            return -1;
        }    
    }
    /**
     * Inserts the purchased items table
     * @param order
     * @return 
     */
    private int insertPurchasedItems(Order order, Connection conn){
        try{
            ArrayList<PurchasedItem> purchasedItem = order.getPurchasedItems();
            int size = purchasedItem.size();
            
            PreparedStatement insertStmt = null;
            String sql = SQL.INSERTPURCHASEDITEMS;
            insertStmt = conn.prepareStatement(sql);
            for(int i=0; i<size; i++){
                PurchasedItem pi = (PurchasedItem) purchasedItem.get(i);
                pi.setOrderId(order.getOrderId());
                insertStmt.setLong(1, pi.getPurchaseItemId());
                insertStmt.setLong(2, pi.getItemId());
                insertStmt.setLong(3, pi.getOrderId());
                insertStmt.setDouble(4,pi.getPriceAdjustedAmount());
                insertStmt.setDouble(5,pi.getBasePrice());
                insertStmt.setDouble(6,pi.getTotalPrice());
                insertStmt.setInt(7,pi.getIsToBePicked());
                insertStmt.setDate(8,pi.getDateModified());
                insertStmt.setDate(9,pi.getDateTimeCreated());
                insertStmt.executeUpdate();
            }
            return 1;
        }
        catch(Exception e){
            e.printStackTrace();
            return -1;
        }
    }
}
